package com.dy.handler;

import cn.dev33.satoken.exception.NotLoginException;
import com.dy.utils.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Author: dy
 * @date: 2024/5/7 10:14
 * @ClassDescription: 统一异常拦截器
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 全局异常拦截
     * @param e
     * @return {@link ApiResult}
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ApiResult exceptionHandler(Exception e){
        e.printStackTrace();
        return ApiResult.error(e.getMessage());
    }

    /**
     * validation 统一异常处理
     * @param e e
     * @return {@link ApiResult}<{@link ?}>
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiResult handleValidationExceptions(MethodArgumentNotValidException e) {
        // 从异常中获取验证结果对象 BindingResult
        BindingResult bindingResult  = e.getBindingResult();
        // 只返回第一个验证错误的信息
        FieldError firstError = bindingResult.getFieldError();
        if (firstError == null) {
            return ApiResult.error("参数校验失败");
        }
        String defaultMessage = firstError.getDefaultMessage();
        // 返回统一的错误响应
        log.error("参数校验失败:{}", defaultMessage);
        return ApiResult.error(defaultMessage);
    }

    /**
     * 登录异常拦截
     * @param e e
     * @return {@link ApiResult}
     */
    @ExceptionHandler(NotLoginException.class)
    @ResponseBody
    public ApiResult LoginException(NotLoginException e) {
        return ApiResult.error(e.getMessage());
    }
}
